#ifndef _math_traits_hpp_
#define _math_traits_hpp_

/** \file math_traits.hpp Defines some template metafunctions to query whether a given type fulfills the vector or a scalar interface.
 *  \note atm only the following types are supported:
 *  - all integral and floating point builtin types
 *  - std::vector, std::valarray
 *  - boost::array
 *  - Point, Index
 *  - c-like arrays like \code int vec[10]; \endcode
 *  \author Adrian Schweizer
 *  \date   7.7.2007
 */


#include "math_common.hpp"

namespace core {

    namespace math {

        using boost::mpl::false_;
        using boost::mpl::true_;
        using boost::mpl::int_;
        using boost::mpl::size_t;
        using boost::mpl::if_;

        //mathematical type traits

        /** \brief template metafunction to query whether a type is a scalar
         *
         *  Example Usage:
         *  \code 
         *  typedef math::is_scalar<int>::type                  a;  // returns true_
         *  typedef math::is_scalar<std::vector<int> >::type    b;  // returns false_
         *  typedef math::is_scalar<double[10]>::type           c;  // false_
         *  bool really = typedef math::is_scalar<Point>::value;    // false
         *  \endcode
         *  this is true for types that implement all the operators a normal real 
         *  has (+,-,/,*,+=,-=,/=,*=, ==,<,>,<=,>=)
         */
        template<class T>
            struct is_scalar    :   public false_
            { };

        /** \brief template metafunction to check whether a type is a vector or not
         *
         *  Example Usage: 
         *  \code 
         *  typedef math::is_vector<int>::type                  a;  // returns false_
         *  typedef math::is_vector<std::vector<int> >::type    b;  // returns true_
         *  bool really = typedef math::is_vector<std::vector<int> >::value;  // returns true
         *  typedef math::is_vector<double[10]>::type           c;  // true_
         *  bool really1 = typedef math::is_vector<Point>::value;   // true
         *  \endcode
         *  In general this metafunction evaluates to \a true_ if the type in question implements operator[](int index)
         *  and the underlying field type is a scalar.
         */
        template<class T>
            struct is_vector    :   public false_
            { };

    } //namespace math

} // namespace core

#include "detail/math_traits_spec.hpp"

#endif // _math_traits_hpp_
